﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using NetSurveillance.WebApp.Binders;
using NetSurveillance.WebApp.DataServices.Models;
using NetSurveillance.WebApp.Models;
using NetSurveillance.WebApp.Utilities;

namespace NetSurveillance.WebApp.Controllers
{
    public class WhiteListController : BaseController
    {
        public ActionResult WhiteListSet()
        {
            var readWhiteListDatas = TempData["returnWhiteListDatas"] as string;
            if (string.IsNullOrWhiteSpace(readWhiteListDatas) && TempData.ContainsKey("whiteListDatas"))
                readWhiteListDatas = TempData["whiteListDatas"] as string;
            if (readWhiteListDatas != null)
            {
                string[] whiteListModels = readWhiteListDatas.Split(new[] {'θ'});
                if (whiteListModels.Length == 4)
                {
                    ViewBag.Domians = whiteListModels[0];
                    ViewBag.Macs = whiteListModels[1];
                    ViewBag.Ports = whiteListModels[2];
                    ViewBag.Ips = whiteListModels[3];
                }
            }
            else
            {
                LoadWLSetViewData();
            }
            return View();
        }

        [HttpPost]
        public ActionResult WhiteListSet([JsonBinder]WhiteListModel whiteListModel)
        {
            var listWhiteListModels = GetWhiteListModelsOfValidaSuccess(whiteListModel);
            bool sendActionSucc = true;
            var wlEle = ActionXmlUtility.Instance.CreateWhiteListElement(listWhiteListModels);
            var actionEle =
                ActionXmlUtility.Instance.GeneratorActionXml(ActionXmlUtility.Instance.CreateActionRootElement(), wlEle);
            if (!Connector.SendAction(actionEle, PresetValues.MonitorIp, PresetValues.MonitorPort))
            {
                sendActionSucc = false;
                ModelState.AddModelError("", Resources.MessageResource.SendActionError);
            }
            if (sendActionSucc && listWhiteListModels != null)
            {
                var servicesResult = DataProvider.WhiteListService.SaveAll(listWhiteListModels, CurrentTask.Id);
                ModelState.AddModelError("",
                                         !servicesResult.ExecutedSuccess
                                             ? servicesResult.Message
                                             : Resources.MessageResource.Save_Success);
            }
            LoadWLSetViewData();
            return View();
        }

        private void LoadWLSetViewData()
        {
            var wlModels = DataProvider.WhiteListService.GetAllModels(false, p => p.TaskId == CurrentTask.Id);
            foreach (var wlGroup in wlModels.GroupBy(p => p.Type))
            {
                switch (wlGroup.Key.ToLower())
                {
                    case "domain":
                        ViewBag.Domians = string.Join("\r\n", wlGroup.OrderBy(p => p.SortOrder).Select(p => p.DomainName));
                        break;
                    case "mac":
                        ViewBag.Macs = string.Join("\r\n", wlGroup.OrderBy(p => p.SortOrder).Select(p => p.Mac));
                        break;
                    case "port":
                        ViewBag.Ports = string.Join("\r\n",
                                                    wlGroup.OrderBy(p => p.SortOrder)
                                                           .Select(
                                                               p =>
                                                               string.Format("{0}{1}", p.PortStart,
                                                                             p.PortEnd.HasValue
                                                                                 ? ("-" + p.PortEnd)
                                                                                 : string.Empty)));
                        break;
                    case "ip":
                        ViewBag.Ips = string.Join("\r\n",
                                                  wlGroup.OrderBy(p => p.SortOrder)
                                                         .Select(
                                                             p =>
                                                             string.Format("{0}{1}", p.IpStart,
                                                                           !string.IsNullOrWhiteSpace(p.IpEnd)
                                                                               ? ("-" + p.IpEnd)
                                                                               : string.Empty)));
                        break;
                }
            }
        }

        private IList<WhiteList> GetWhiteListModelsOfValidaSuccess(WhiteListModel whiteListModel)
        {
            var listWhiteListModels = new List<WhiteList>();
            if (whiteListModel.Domains != null && whiteListModel.Domains.Any())
            {
                for (int i = 0; i < whiteListModel.Domains.Count(); i++)
                {
                    var domainName = whiteListModel.Domains[i];
                    if (string.IsNullOrWhiteSpace(domainName)) continue;
                    var whiteListObject = new WhiteList
                        {
                            Type = "Domain",
                            DomainName = domainName,
                            TaskId = CurrentTask.Id,
                            SortOrder = i
                        };
                    listWhiteListModels.Add(whiteListObject);
                }
            }
            if (whiteListModel.Macs != null && whiteListModel.Macs.Any())
            {
                for (int i = 0; i < whiteListModel.Macs.Count(); i++)
                {
                    var mac = whiteListModel.Macs[i];
                    if (string.IsNullOrWhiteSpace(mac)) continue;
                    var whiteListObject = new WhiteList
                        {
                            Type = "Mac",
                            Mac = mac,
                            TaskId = CurrentTask.Id,
                            SortOrder = i
                        };
                    listWhiteListModels.Add(whiteListObject);
                }
            }
            if (whiteListModel.Ports != null && whiteListModel.Ports.Any())
            {
                for (int i = 0; i < whiteListModel.Ports.Count(); i++)
                {
                    var port = whiteListModel.Ports[i];
                    if (port == null) continue;
                    var whiteListObject = new WhiteList
                        {
                            Type = "Port",
                            PortStart = port.PortStart,
                            TaskId = CurrentTask.Id,
                            SortOrder = i
                        };
                    if (port.PortEnd > 0)
                        whiteListObject.PortEnd = port.PortEnd;
                    listWhiteListModels.Add(whiteListObject);
                }
            }
            if (whiteListModel.Ips != null && whiteListModel.Ips.Any())
            {
                for (int i = 0; i < whiteListModel.Ips.Count(); i++)
                {
                    var ip = whiteListModel.Ips[i];
                    if (ip == null) continue;
                    var whiteListObject = new WhiteList
                        {
                            Type = "Ip",
                            IpStart = ip.IpStart,
                            TaskId = CurrentTask.Id,
                            SortOrder = i
                        };
                    if (!string.IsNullOrWhiteSpace(ip.IpEnd))
                        whiteListObject.IpEnd = ip.IpEnd;
                    listWhiteListModels.Add(whiteListObject);
                }
            }
            return listWhiteListModels;
        }

        [HttpPost]
        public ActionResult SelectHosts(string whiteListModel)
        {
            var hosts = DataProvider.HostService.GetAllModels(false, p => p.TaskId == CurrentTask.Id);
            string[] whiteListModels = whiteListModel.Split(new[] { 'θ' });
            IList<long> selectedHostIds = new List<long>();
            if (whiteListModels.Length == 4)
            {
                string selectedIpStr = whiteListModels[3];
                string[] selectedIps = selectedIpStr.Split(new[] { "\r\n" },
                                                           StringSplitOptions.RemoveEmptyEntries);
                selectedHostIds = hosts.Where(p => selectedIps.Contains(p.IP)).Select(p => p.Id).ToList();
                ViewBag.SelectedHostHtml = string.Join("", selectedIps.Select(p => string.Format("<p>{0}</p>", p)));
            }
            ViewBag.TreeNode = SerializeObject(ZTreeUtility.GenerateHostNodes(hosts, selectedHostIds));
            TempData["whiteListDatas"] = whiteListModel;
            return View();
        }

        [HttpPost]
        public ActionResult SaveSelectHosts([JsonBinder]long[] hostIds, string selectedWhiteListIps)
        {
            if (hostIds == null)
            {
                return RedirectToWhiteListSetAction(selectedWhiteListIps);
            }
            var serviceResult = DataProvider.WhiteListService.SaveWhiteListHost(CurrentTask.Id, hostIds);
            if (serviceResult.ExecutedSuccess)
                return RedirectToWhiteListSetAction(selectedWhiteListIps);
            ModelState.AddModelError("", serviceResult.Message);
            var hosts = DataProvider.HostService.GetAllModels(false, p => p.TaskId == CurrentTask.Id);
            ViewBag.TreeNode = SerializeObject(ZTreeUtility.GenerateHostNodes(hosts, hostIds));
            return View("SelectHosts");
        }

        private ActionResult RedirectToWhiteListSetAction(string selectedWhiteListIps)
        {
            string readWhiteListDatas = TempData["whiteListDatas"] as string;
            if (readWhiteListDatas != null)
            {
                readWhiteListDatas += selectedWhiteListIps;
                TempData["returnWhiteListDatas"] = readWhiteListDatas;
            }
            else
            {
                TempData["returnWhiteListDatas"] = selectedWhiteListIps;
            }
            return RedirectToAction("WhiteListSet");
        }
    }
}
